Skip to content

Add custom-pricing overlay above models.dev and builtin rates - #3016

Merged
steipete merged 7 commits into
steipete:mainfrom
Yuxin-Qiao:feat/spend-c-pricing
Aug 18, 2026
Merged

Add custom-pricing overlay above models.dev and builtin rates#3016
steipete merged 7 commits into
steipete:mainfrom
Yuxin-Qiao:feat/spend-c-pricing

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Load custom-pricing.json as an exact-match overlay: overlay > models.dev > builtin.
  • Treat missing overlay fields as unknown (not free) and 0 as free.
  • Invalidate the Codex pricing fingerprint when the overlay changes so caches rescan.

Stacked PR 2/5 (Wave C). Depends on #3015; review the custom-pricing commit once that lands.

Review follow-up

  • codexAggregateCostUSD consults the overlay (including free 0) before bundled/models.dev rates.
  • Overlay JSON is loaded once per scan and passed through CodexReportDayPricingContext.customPricing.
  • Overlay cost helpers live in CostUsagePricing+Overlay.swift so CostUsagePricing stays under type_body_length.

Test plan

Fixtures only. No Keychain, no live accounts, no developer Application Support overlay file.

CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1
make check
# Codex parser hash is current (b7726c3088c14277)
# Done linting! Found 0 violations, 0 serious in 1928 files.

CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 swift test --filter \
  'aggregate fallback consults the overlay before bundled rates'
✔ aggregate fallback consults the overlay before bundled rates
  • Overlay aggregate fallback test above
  • CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 swift test --filter CostUsageCustomPricingTests
  • Overlay fixture does not read the developer Application Support file
  • Unknown model stays unpriced instead of showing $0

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f92c6255e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +556 to +559
let overlay = customPricing ?? self.customPricingOverlay()
if let rates = overlay.rates(providerID: self.codexModelsDevProviderID, model: model)
?? overlay.rates(model: model)
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply custom pricing to aggregate fallback

When cached day totals are valid but their pricing rows are absent or untrusted, makeCodexBilledDayEntry falls back to codexAggregateCostUSD, which still resolves only models.dev or bundled rates and never reaches this overlay block. Such reports therefore ignore a matching custom rate—including explicit free rates—and show the wrong spend; the aggregate path needs to consult the same overlay before its existing fallbacks.

Useful? React with 👍 / 👎.

modelsDevCacheRoot: URL? = nil,
customPricing: CostUsageCustomPricing? = nil) -> Double?
{
let overlay = customPricing ?? self.customPricingOverlay()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Load the pricing overlay once per pricing pass

For normal Codex reports, codexResolvedCostUSD calls this method once per usage row, so omitting customPricing causes every row to perform a filesystem check and, when the overlay exists, reread, parse, and SHA-256 hash the JSON file. Large histories can consequently incur thousands of redundant file parses during each report; load the overlay into the scan/pricing context once and pass it through.

Useful? React with 👍 / 👎.

Comment on lines +17 to +21
let dayKey = unixMs.map {
CostUsageDayRange.dayKey(
from: Date(timeIntervalSince1970: TimeInterval($0) / 1000),
calendar: range.calendar)
} ?? range.untilKey

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid assigning undated forks to every requested window

If an unresolved fork has neither session timestamp—possible for legacy/incomplete cached metadata—this fallback assigns it to the query's untilKey. The same old fork is therefore reported as an unmetered request in every 7-day or 30-day window, always on that window's final day, regardless of when its file existed; use the available mtimeUnixMs as the fallback or exclude entries whose date cannot be established.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 17, 2026
@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed August 17, 2026, 4:12 PM ET / 20:12 UTC.

ClawSweeper review

What this changes

The stacked branch adds a custom-pricing JSON overlay for Codex cost estimates and carries prerequisite spend-provenance, time-zone, fork-accounting, and cache changes.

Merge readiness

Blocked until real behavior proof from a real setup is added - 7 items remain

Keep open: the updated head still has two source-confirmed pricing errors, lacks real after-fix behavior proof, and introduces a persistent user configuration contract without maintainer product confirmation.

Priority: P2
Reviewed head: 725419a59765ec296cd413245b4959eef8d7450b
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The patch has useful focused tests, but two correctness blockers and fixture-only proof keep it below merge readiness.
Proof confidence 🦪 silver shellfish (2/6) Needs real behavior proof before merge: The PR body reports fixture tests only; it needs a redacted after-fix local scan or terminal transcript showing an overlay changes a real cost estimate before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦐 gold shrimp (3/6) 2 actionable review findings remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The PR body reports fixture tests only; it needs a redacted after-fix local scan or terminal transcript showing an overlay changes a real cost estimate before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 6 items Current main boundary: Current main resolves Codex estimates through models.dev and bundled pricing; it does not contain the proposed custom overlay path.
Incomplete overlay falls through: A matching overlay with a missing required rate returns nil, and this branch then continues into models.dev or bundled pricing, contrary to the overlay's stated unknown-rate contract.
Existing defensive token handling: The established Codex pricing helper clamps cached reads to total input and cache writes to the remaining input; the new overlay helper does neither.
Findings 2 actionable findings [P1] Prevent incomplete overlays from falling back
[P2] Clamp cached and cache-write tokens before pricing
Security None None.

How this fits together

CodexBar scans local Codex sessions, resolves token prices from models.dev or bundled rates, and presents cached cost estimates in usage and spend views. This PR inserts a local JSON rate source ahead of those existing pricing sources.

flowchart LR
A[Local Codex sessions] --> B[Usage scanner]
C[Custom pricing JSON] --> D[Pricing resolver]
E[Models.dev catalog] --> D
F[Bundled rates] --> D
B --> D
D --> G[Cached cost report]
G --> H[Usage and spend views]
Loading

Decision needed

Question Recommendation
Should CodexBar support custom-pricing.json as a stable user-facing override contract for local cost estimates? Keep managed pricing sources for now: Do not merge the user-editable overlay and retain the documented models.dev plus bundled fallback model until a supported configuration direction is approved.

Why: The branch adds a persisted configuration surface and pricing precedence not described by the current models.dev and bundled-rate documentation; maintainers must decide whether to support that contract long-term.

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The PR body reports fixture tests only; it needs a redacted after-fix local scan or terminal transcript showing an overlay changes a real cost estimate before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Prevent incomplete overlays from falling back (P1) - A matching entry with a missing active rate returns nil from estimatedCodexCostUSD, but this if let then falls through to models.dev or bundled pricing. That violates the documented overlay contract that missing fields remain unknown; distinguish no matching entry from an incomplete matching entry and return nil for the latter.
  • Clamp cached and cache-write tokens before pricing (P2) - The overlay bills every nonnegative cached or cache-write token even if it exceeds total input. The existing Codex helper clamps cached reads to input and writes to the remainder, so malformed rows become more expensive only when the overlay is enabled.
  • Resolve merge risk (P1) - A persistent local rate override can change displayed spend for users who adopt it; its supported path, schema, precedence, and recovery behavior need an explicit compatibility contract.
  • Resolve merge risk (P1) - The 32-file stacked branch includes prerequisite cache and settings changes, so it needs refreshed integration review after its dependency lands.
  • Complete next step (P2) - Maintainer product direction for the new persistent configuration surface and contributor-supplied real behavior proof are required before a safe merge path can be chosen.

Findings

  • [P1] Prevent incomplete overlays from falling back — Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing+Overlay.swift:14-23
  • [P2] Clamp cached and cache-write tokens before pricing — Sources/CodexBarCore/Vendored/CostUsage/CostUsageCustomPricing.swift:133-135
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Branch scope 32 files; production +1,093/-203, tests +345/-1 The merge includes stacked prerequisite cache and settings work alongside the pricing overlay.

Merge-risk options

Maintainer options:

  1. Repair override semantics before merge (recommended)
    Distinguish a missing overlay entry from an incomplete matching entry, clamp cache token classes like the existing helper, and add focused regression coverage.
  2. Pause the configuration contract
    Keep the current documented pricing sources if maintainers do not want to support a persistent user-editable rate schema.

Technical review

Best possible solution:

Keep the documented managed pricing sources unless the owner sponsors a stable advanced override; if sponsored, narrow and document the JSON contract, preserve unknown-rate behavior, clamp malformed token classes, and prove a real local scan.

Do we have a high-confidence way to reproduce the issue?

Yes for the patch defects: call the pricing resolver with a matching overlay that omits an active token class, or with cached tokens above input; current source shows the wrong fallback or overbilling path.

Is this the best way to solve the issue?

No: the implementation needs the two narrow correctness repairs, real-scan evidence, and maintainer confirmation that the JSON file is a supported configuration interface.

Full review comments:

  • [P1] Prevent incomplete overlays from falling back — Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing+Overlay.swift:14-23
    A matching entry with a missing active rate returns nil from estimatedCodexCostUSD, but this if let then falls through to models.dev or bundled pricing. That violates the documented overlay contract that missing fields remain unknown; distinguish no matching entry from an incomplete matching entry and return nil for the latter.
    Confidence: 0.99
  • [P2] Clamp cached and cache-write tokens before pricing — Sources/CodexBarCore/Vendored/CostUsage/CostUsageCustomPricing.swift:133-135
    The overlay bills every nonnegative cached or cache-write token even if it exceeds total input. The existing Codex helper clamps cached reads to input and writes to the remainder, so malformed rows become more expensive only when the overlay is enabled.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f7723d33a169.

Labels

Label changes:

  • add merge-risk: 🚨 compatibility: A new persistent rate source and cache invalidation path can change existing cost-report behavior once users adopt the overlay.

Label justifications:

  • P2: Incorrect local cost estimates have bounded but user-visible spend-reporting impact.
  • merge-risk: 🚨 compatibility: A new persistent rate source and cache invalidation path can change existing cost-report behavior once users adopt the overlay.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body reports fixture tests only; it needs a redacted after-fix local scan or terminal transcript showing an overlay changes a real cost estimate before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

What I checked:

Likely related people:

  • steipete: Recent main history includes vendor-pricing reconciliation in the same shared pricing implementation. (role: recent pricing-area contributor; confidence: high; commits: ad400726bba6; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing.swift, docs/model-pricing.md)
  • Yuxin-Qiao: Main history credits prior provider-qualified Codex pricing and pricing-cache work, in addition to the current proposal. (role: prior Codex-pricing contributor; confidence: high; commits: 728ca278d440, fbe70c3e9c65; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing.swift, Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricingKey.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Fix the incomplete-entry fallback and malformed-token accounting with regression tests.
  • Add a redacted after-fix real local scan or terminal transcript; update the PR body to trigger re-review.
  • Obtain maintainer sponsorship for the supported custom-pricing contract.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (1 earlier review cycle)
  • reviewed 2026-08-17T18:22:45.281Z sha 6f92c62 :: needs real behavior proof before merge. :: [P1] Apply the overlay to aggregate fallback pricing | [P2] Load custom pricing once for each report | [P2] Do not assign undated forks to the query end day

Yuxin-Qiao and others added 6 commits August 18, 2026 02:53
Pinned calendars now reach cached Codex reads, vendor-reported costs keep their source, and shorter summaries no longer inherit snapshot-wide metered spend.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Cached day totals now honor overlay rates, including explicit free rates, without rereading custom-pricing.json for every usage row.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…imit.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/spend-c-pricing branch from 6f92c62 to 725419a Compare August 17, 2026 19:26
@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 725419a597

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

modelsDevCacheRoot: URL? = nil,
customPricing: CostUsageCustomPricing? = nil) -> Double?
{
if let cost = (customPricing ?? self.customPricingOverlay()).estimatedCodexCostUSD(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve unknown rates from matching overlay entries

When a matching custom entry omits a rate needed by the current token mix, estimatedCodexCostUSD returns nil, but this if let treats that exactly like “no overlay matched” and continues into models.dev or bundled pricing. For example, { "gpt-5.4": { "input": 2.5 } } with output tokens silently produces the standard full-model estimate even though the overlay contract says missing fields remain unknown; distinguish a missing match from a matched-but-incomplete entry and return nil for the latter.

Useful? React with 👍 / 👎.

Comment on lines +133 to +135
let cached = max(0, cachedInputTokens)
let written = max(0, cacheWriteInputTokens)
let uncachedInput = max(0, inputTokens - cached - written)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clamp custom cached tokens to total input

When a malformed or inconsistent usage row reports cached input greater than total input, this path bills every reported cached token, unlike the existing Codex pricing path that clamps cached reads to inputTokens; cache writes can likewise exceed the remaining input. Thus enabling a custom overlay can invent input and overstate the same row that bundled pricing handles defensively, so clamp cached reads to total input and writes to the remainder before computing uncachedInput.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. label Aug 17, 2026
@steipete
steipete merged commit 725419a into steipete:main Aug 18, 2026
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants